package br.com.wai2008.socket.server;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * This class manages the Socket Server for client requests. It manages the
 * threads and the state for the server.
 * 
 * @since 
 * 		September, 2008.
 * 
 * @version
 * 		WAI2008 - version 1.0
 * 
 * @author 
 * 		Andre Romero Goncales
 */
public class SocketServer {

	/**
	 * Server Thread's list.
	 */
	private static List<SocketServerThread> threads = null;
	
	/**
	 * Server's state. Could be STOPPED, RUNNING or CRASHED.
	 * 
	 * @see
	 * 		br.com.wai2008.socket.server.SocketServerState
	 */
	private static int socketServerState = SocketServerState.STATE_STOPPED;

	/**
	 * Start the server.
	 */
	public static void startServer() {
		System.out.println("[SocketServer] Starting server...");
		threads = new ArrayList<SocketServerThread>();
		SocketServerThread ssThread = new SocketServerThread();
		ssThread.start();
		threads.add(ssThread);
		System.out.println("[SocketServer] Current Thread: " + ssThread.getId());
		socketServerState = SocketServerState.STATE_RUNNING;
		System.out.println("[SocketServer] Server Started");
	}

	/**
	 * Stop the server and remove all threads that are been executed.
	 * 
	 * @throws
	 * 		IOException if an error occur while stopping the listener.
	 */
	public static void stopServer() throws IOException {
		System.out.println("[SocketServer] Stopping server...");
		for (int i=0; i < threads.size(); i++) {
			try {
				threads.get(i).stopListener();
			} catch (IOException e) {
				e.printStackTrace();
				socketServerState = SocketServerState.STATE_CRASHED;
				throw e;
			}
			threads.remove(threads.get(i));
		}
		socketServerState = SocketServerState.STATE_STOPPED;
		System.out.println("[SocketServer] Server Stopped");
	}

	/**
	 * Remove a specific thread from the server thread's list.
	 * 
	 * @param
	 * 		ssThread the thread to be removed.
	 */
	public static void removeThread(SocketServerThread ssThread) {
		System.out.println("[SocketServer] Removing thread " + ssThread.getId() + " from server...");
		threads.remove(ssThread);
		System.out.println("[SocketServer] Thread " + ssThread.getId() + " removed from server");
	}

	/**
	 * Add a new thread in server thread's list and start it.
	 */
	public static void startNewThread() {
		System.out.println("[SocketServer] Adding new thread on server...");
		SocketServerThread ssThread = new SocketServerThread();
		ssThread.start();
		threads.add(ssThread);
		System.out.println("[SocketServer] Current Thread: " + ssThread.getId());
		System.out.println("[SocketServer] Thread added on server");
	}

	/**
	 * Get the Server's state.
	 * 
	 * @return
	 * 		0 - if state is STOPPED.<br>
	 * 		1 - if state is RUNNING.<br>
	 * 		2 - if state is CRASHED.
	 * 
	 * @see
	 * 		br.com.wai2008.socket.server.SocketServerState
	 */
	public static int getSocketServerState() {
		return socketServerState;
	}

	/**
	 * Get the Server's state.
	 * 
	 * @return
	 * 		STOPPED, RUNNING, CRASHED or NOT FOUND.
	 * 
	 * @see
	 * 		br.com.wai2008.socket.server.SocketServerState
	 */
	public static String getSocketServerStateName() {
		switch(socketServerState) {
		case (SocketServerState.STATE_STOPPED):	
			return "STOPPED";
		case (SocketServerState.STATE_RUNNING):	
			return "RUNNING";
		case (SocketServerState.STATE_CRASHED):	
			return "CRASHED";
		default:
			return "NOT FOUND";
		}
	}
	
	public static void main (String[] args) {
		System.out.println("[ServerSocket] Starting server...");
		SocketServer.startServer();
		System.out.println("[ServerSocket] Server Started!");
	}
}
